package com.gitee.openviducn.inspector.config;

import com.alibaba.fastjson.JSONObject;
import eu.bitwalker.useragentutils.UserAgent;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Objects;

/**
 * 请求接口日志
 * @Author: https://gitee.com/wesleyOne
 * @Date: 02.29 2020
 */
@Aspect
@Priority(1)
@Component
public class RestLogAspect {

    private Logger restApiLog = LoggerFactory.getLogger("restApi");

    private ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("execution(public * com.gitee.openviducn.inspector.rest..*(..))")
    public void httpResponse() {
    }

    @Before("httpResponse()")
    public void doBefore(JoinPoint joinPoint){
        //开始计时
        startTime.set(System.currentTimeMillis());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (Objects.isNull(attributes)) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        // 获取请求头中的User-Agent
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        restApiLog.info("{} {}.{} {} {} {}"
                ,request.getRequestURL().toString()
                ,userAgent.getBrowser().toString(),userAgent.getBrowserVersion()
                ,userAgent.getOperatingSystem().toString(),request.getRemoteAddr()
                ,request.getMethod());
        Object[] args = joinPoint.getArgs();
        String paramter = null;
        if (Objects.nonNull(args)) {
            try {
                paramter = JSONObject.toJSONString(args);
            } catch (Exception e) {
                paramter = Arrays.toString(args);
            }
        }
        restApiLog.info("{}.{} 请求参数：{}",joinPoint.getSignature().getDeclaringTypeName() , joinPoint.getSignature().getName()
                , paramter);
    }

    @AfterReturning(returning = "ret" , pointcut = "httpResponse()")
    public void doAfterReturning(Object ret){
        restApiLog.info("cast:{}ms,result：{}" ,System.currentTimeMillis() - startTime.get(), JSONObject.toJSONString(ret));
        startTime.remove();
    }
}
